﻿#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <list>
#include "../../../NetEngine_Linux/NetEngine_SourceCode/XyRyNet_CommHdr.h"
#include "../../../NetEngine_Linux/NetEngine_SourceCode/XyRyNet_Types.h"
#include "../../../NetEngine_Linux/NetEngine_SourceCode/NetEngine_AvCoder/NetEngine_AVCollect/AVCollect_Define.h"
#include "../../../NetEngine_Linux/NetEngine_SourceCode/NetEngine_AvCoder/NetEngine_AudioCoder/AudioCoder_Define.h"
#include "../../../NetEngine_Linux/NetEngine_SourceCode/NetEngine_AvCoder/NetEngine_AudioCoder/AudioCoder_Error.h"

//g++ -std=gnu++11 -Wall -g Test_ForAudio.cpp -o Test_ForAudio -L ../../../NetEngine_Linux/NetEngine_Release/NetEngine_Release/NetEngine_BaseLib -L ../../../NetEngine_Linux/NetEngine_Release/NetEngine_Release/NetEngine_AvCoder -lNetEngine_BaseLib -lNetEngine_AudioCoder -Wl,-rpath=./:../../../NetEngine_Linux/NetEngine_Release/NetEngine_Release/NetEngine_BaseLib:../../../NetEngine_Linux/NetEngine_Release/NetEngine_Release/NetEngine_AvCoder,--disable-new-dtags

void __stdcall AudioCodec_Stream_Callback(XNETHANDLE xhNet, uint8_t *pszBuffer, int nLen, AVCODEC_AUDIO_INFO *pSt_AudioInfo, LPVOID lParam)
{
    FILE *pSt_File = (FILE *)lParam;
    printf("%llu write:%d\n", xhNet, nLen);
    fwrite(pszBuffer, 1, nLen, pSt_File);
}

void Audio_ListCodec()
{
    list<AVCODEC_AUDIO_CODECLIST> stl_ListEncoder;
    list<AVCODEC_AUDIO_CODECLIST> stl_ListDecoder;
    AudioCodec_Help_GetList(&stl_ListEncoder, &stl_ListDecoder);

    list<AVCODEC_AUDIO_CODECLIST>::const_iterator stl_ListEncoderIterator = stl_ListEncoder.begin();
    for (; stl_ListEncoderIterator != stl_ListEncoder.end();stl_ListEncoderIterator++)
    {
        printf("%d = %s\n", stl_ListEncoderIterator->nCodecType, stl_ListEncoderIterator->tszCodecName);
    }
    list<AVCODEC_AUDIO_CODECLIST>::const_iterator stl_ListDecoderIterator = stl_ListDecoder.begin();
    for (; stl_ListDecoderIterator != stl_ListDecoder.end(); stl_ListDecoderIterator++)
    {
        printf("%d = %s\n", stl_ListEncoderIterator->nCodecType, stl_ListEncoderIterator->tszCodecName);
    }
}

void Audio_Encode()
{
    XNETHANDLE xhCoder;
    int nLen = 320;

    if (!AudioCodec_Stream_EnInit(&xhCoder, ENUM_AVCODEC_AUDIO_TYPE_G711A, 8000, 1, 0, 0, ENUM_AVCOLLECT_AUDIO_SAMPLE_FMT_S16, nLen))
    {
        printf("AudioCodec_Stream_EnInit\n");
        return;
    }
    FILE* pSt_File = fopen("E:\\audio\\8k_1_16.pcm", "rb");
    FILE* pSt_FileAac = fopen("E:\\audio\\mix.g711a", "wb");

    nLen = 400;
    while (1)
    {
        TCHAR tszEnBuffer[40960];
        TCHAR tszPCMBuffer[40960];

        memset(tszEnBuffer, '\0', sizeof(tszEnBuffer));
        memset(tszPCMBuffer, '\0', sizeof(tszPCMBuffer));

        int nRet = fread(tszPCMBuffer, 1, nLen, pSt_File);
        if (nRet <= 0)
        {
            break;
        }
        int nWet = 0;
        if (AudioCodec_Stream_EnCodec(xhCoder, (uint8_t*)tszPCMBuffer, nLen, (uint8_t*)tszEnBuffer, &nWet))
        {
            if (nWet > 0)
            {
                fwrite(tszEnBuffer, 1, nWet, pSt_FileAac);
            }
        }
    }
    fclose(pSt_File);
    fclose(pSt_FileAac);
    AudioCodec_Stream_Destroy(xhCoder);
}
void Audio_DeCodec()
{
    XNETHANDLE xhCoder;

    FILE *pSt_FileEnCode = fopen("Audio.g711a", "rb");
    FILE *pSt_FileDeCodec = fopen("Audio.pcm", "wb");

    AVCODEC_AUDIO_INFO st_AudioInfo;
    memset(&st_AudioInfo, '\0', sizeof(AVCODEC_AUDIO_INFO));

    st_AudioInfo.nSampleRate = 8000;
    st_AudioInfo.nChannle = 1;
    st_AudioInfo.enSampleFmt = ENUM_AVCOLLECT_AUDIO_SAMPLE_FMT_S16;
    if (!AudioCodec_Stream_DeInit(&xhCoder, ENUM_AVCODEC_AUDIO_TYPE_G711A, AudioCodec_Stream_Callback, pSt_FileDeCodec,&st_AudioInfo))
    {
        printf("AudioCodec_Stream_DeInit\n");
        return;
    }
    while (1)
    {
        TCHAR tszEnBuffer[20480];
        memset(tszEnBuffer, '\0', sizeof(tszEnBuffer));

        int nRet = fread(tszEnBuffer, 1, 20480, pSt_FileEnCode);
        if (nRet <= 0)
        {
            break;
        }

        AudioCodec_Stream_DeCodec(xhCoder, (uint8_t *)tszEnBuffer, nRet);
    }
    AudioCodec_Stream_DeCodec(xhCoder, NULL, 0);
    fclose(pSt_FileEnCode);
    fclose(pSt_FileDeCodec);
    AudioCodec_Stream_Destroy(xhCoder);
}
void Audio_Resample()
{
    XNETHANDLE xhCoder;
    if (!AudioCodec_Stream_EnInit(&xhCoder, ENUM_AVCODEC_AUDIO_TYPE_AAC, 8000, 1, 64000, 0, ENUM_AVCOLLECT_AUDIO_SAMPLE_FMT_FLTP))
    {
        printf("AudioCodec_Stream_EnInit\n");
        return;
    }
    int nLen = 0;
    if (!AudioCodec_Stream_SetResample(xhCoder, &nLen, 8000, 8000, ENUM_AVCOLLECT_AUDIO_SAMPLE_FMT_S16, ENUM_AVCOLLECT_AUDIO_SAMPLE_FMT_FLTP, 1, 1))
    {
        printf("AudioCodec_Stream_ResamplerInit\n");
        return;
    }
    nLen = 557;
    FILE *pSt_File = fopen("Audio.pcm", "rb");
    FILE *pSt_FileAac = fopen("Audio.aac", "wb");
    while (1)
    {
        TCHAR tszEnBuffer[40960];
        TCHAR tszPCMBuffer[40960];

        memset(tszEnBuffer, '\0', sizeof(tszEnBuffer));
        memset(tszPCMBuffer, '\0', sizeof(tszPCMBuffer));

        int nRet = fread(tszPCMBuffer, 1, nLen, pSt_File);
        if (nRet <= 0)
        {
            break;
        }
        int nWet = 0;
        if (AudioCodec_Stream_EnCodec(xhCoder, (uint8_t*)tszPCMBuffer, nLen, (uint8_t*)tszEnBuffer, &nWet))
        {
            if (nWet > 0)
            {
                BYTE byAACHdr[8];
                AudioCodec_Help_GetAACAdts(byAACHdr, 8000, 1, nWet);

                fwrite(byAACHdr, 1, 7, pSt_FileAac);
                fwrite(tszEnBuffer, 1, nWet, pSt_FileAac);
            }
        }
    }
    fclose(pSt_File);
    fclose(pSt_FileAac);
    AudioCodec_Stream_Destroy(xhCoder);
}
void Audio_Filter()
{
    XNETHANDLE xhCoder;
    XNETHANDLE xhFilter;
    if (!AudioCodec_Stream_EnInit(&xhCoder, ENUM_AVCODEC_AUDIO_TYPE_MP3, 44100, ENUM_AVCOLLECT_AUDIO_SAMPLE_FMT_S16P))
    {
        printf("AudioCodec_Stream_EnInit\n");
        return;
    }
    AVCODEC_AUDIO_FILTER st_AudioFilter;
    memset(&st_AudioFilter, '\0', sizeof(AVCODEC_AUDIO_FILTER));

    strcpy(st_AudioFilter.tszArgsName, "volume");
    strcpy(st_AudioFilter.tszArgsValue, "2");
    st_AudioFilter.nChannleLayout = 3;
    st_AudioFilter.nNBSample = 1152;
    st_AudioFilter.nSampleFmt = ENUM_AVCOLLECT_AUDIO_SAMPLE_FMT_S16;
    st_AudioFilter.nSampleRate = 44100;

    if (!AudioCodec_Help_FilterInit(&xhFilter, "sample_fmts=44100:sample_rates=s16p:channel_layouts=stereo", &st_AudioFilter))
    {
        printf("AudioCodec_Help_FilterInit\n");
        return;
    }
    FILE *pSt_File = fopen("E:\\netengineapp\\NetEngine_WINApps\\Debug\\test.pcm", "rb");
    FILE *pSt_FileAac = fopen("E:\\netengineapp\\NetEngine_WINApps\\Debug\\mix.mp3", "wb");
    while (1)
    {
        int nFilterLen = 0;
        TCHAR tszEnBuffer[20480];
        TCHAR tszPCMBuffer[20480];
        TCHAR tszFilterBuffer[20480];

        memset(tszEnBuffer, '\0', sizeof(tszEnBuffer));
        memset(tszPCMBuffer, '\0', sizeof(tszPCMBuffer));
        memset(tszFilterBuffer, '\0', sizeof(tszFilterBuffer));

        int nRet = fread(tszPCMBuffer, 1, st_AudioFilter.nNBSample * 4, pSt_File);
        if (nRet <= 0)
        {
            break;
        }
        if (AudioCodec_Help_FilterCvt(xhFilter, (uint8_t *)tszPCMBuffer, nRet, (uint8_t *)tszFilterBuffer, &nFilterLen))
        {
            int nWet = 0;
            if (AudioCodec_Stream_EnCodec(xhCoder, (uint8_t *)tszFilterBuffer, nFilterLen, (uint8_t *)tszEnBuffer, &nWet))
            {
                if (nWet > 0)
                {
                    fwrite(tszEnBuffer, 1, nWet, pSt_FileAac);
                }
            }
        }

    }
    fclose(pSt_File);
    fclose(pSt_FileAac);
    AudioCodec_Help_FilterDestroy(xhFilter);
    AudioCodec_Stream_Destroy(xhCoder);
}
int main()
{
    //Audio_Encode();
    //Audio_DeCodec();
    Audio_Resample();
    //Audio_Filter();
    return 0;
}
